using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering.Universal;
using UnityEngine.SceneManagement;
using System;
using UnityEngine.UI;

namespace Super
{
	/// <summary>
	/// ����������ű�������������صĺ���
	/// </summary>
	public static class GameUtil
	{
		public static T OpenPanel<T>(List<object> arguments = null) where T : PanelBase
		{
			string panelName = typeof(T).Name;
			PanelBase panelBase = PanelManager.FindPanel(panelName);
			if (panelBase == null)
			{
				string AName = (string)System.Type.GetType(panelName).GetField("AName").GetValue(null);
				GameObject prefab = AssetUtil.ALoadAsset<GameObject>(AName);

				GameObject GO = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity);
				GO.name = panelName;

				panelBase = GO.GetComponent<PanelBase>();
				string parentName = panelBase.canvas.sortingLayerName;
				parentName = parentName.StartsWith("UI") ? parentName : "UINormal";

				Transform rootTF = GetOrCreateSceneRoot("UIRoot", FWConfig.UIRoot);
				GO.transform.SetParent(rootTF.Find(parentName), true);
			}
			panelBase.gameObject.SetActive(true);
			panelBase.transform.SetAsLastSibling();
			Transform parent = panelBase.transform.parent;
			if (parent != null && parent.name.StartsWith("UI"))
			{
				panelBase.GetComponent<Canvas>().sortingLayerName = parent.name;
			}
			
			panelBase.Open(arguments);

			EventManager.Emit(new PanelOpenGE(panelName, panelBase));
			return (T)panelBase;
		}

		public static void ClosePanel<T>() where T : PanelBase
		{
			string panelName = typeof(T).Name;
			PanelBase panelBase = PanelManager.FindPanel(panelName);
			if (panelBase != null)
			{
				panelBase.gameObject.SetActive(false);
				panelBase.Close();
			}
		}

		/// <summary>
		/// ��ȡ��ǰ��Ϸ���ڵ��е�Transform
		/// </summary>
		/// <param name="name">���ڵ�����</param>
		/// <returns></returns>
		public static Transform GetSceneRoot(string name)
		{
			Transform tf = null;
			//�����в���
			GameObject[] gameObjects = SceneManager.GetActiveScene().GetRootGameObjects();
			foreach (GameObject gameObject in gameObjects)
			{
				if (gameObject.name == name)
				{
					tf = gameObject.transform;
					break;
				}
			}

			//DontDestroyObject�����в���
			if (tf == null)
			{
				tf = DataHelperUtil.FindDontDestroyObject(name)?.transform;
			}
			return tf;
		}

		/// <summary>
		/// ��ȡ��ǰ������Ϸ���ڵ��е�Transform
		/// ����û��name���ڵ㣬AName��ֵ��ֱ�Ӵ���name��Ϸ����
		/// AName��ֵ��ͨ����Դ����ʵ��������
		/// </summary>
		/// <param name="name">���ڵ�����</param>
		/// <param name="AName">���ڵ�Ԥ�����Addressable·��</param>
		/// <returns></returns>
		public static Transform GetOrCreateSceneRoot(string name, string AName = "")
		{
			Transform tf = GetSceneRoot(name);

			if (tf == null)         //����AName������Ĭ����Ϸ����
			{
				GameObject go = null;
				if (string.IsNullOrEmpty(AName))
				{
					go = new GameObject(name);
				}
				else
				{
					GameObject prefab = AssetUtil.ALoadAsset<GameObject>(AName);
					go = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity);
					go.name = name;
				}
				tf = go.transform;

			}
			return tf;
		}

		/// <summary>
		/// ��������Ӹ����
		/// </summary>
		/// <param name="camera"></param>
		public static void MainCameraStackAdd(Camera camera)
		{
			Camera mainCamera = DataHelperUtil.GetMainCamera();
			if (mainCamera != null)
			{
				UniversalAdditionalCameraData cameraURPData = mainCamera.GetUniversalAdditionalCameraData();
				List<Camera> cameraStack = cameraURPData.cameraStack;
				if (cameraStack.Contains(camera)) return;
				cameraStack.Add(camera);
			}
		}

		/// <summary>
		/// other�ķ���-1��ߣ�1�ұ�
		/// </summary>
		/// <param name="collision"></param>
		/// <param name="tf"></param>
		/// <returns></returns>
		public static int GetSymbolIntH(GameObject user, GameObject other)
		{
			float offset = user.transform.position.x - other.transform.position.x;
			if (offset > 0)
			{
				return -1;
			}
			return 1;
		}

		/// <summary>
		/// other�ķ���-1���棬1����
		/// </summary>
		/// <param name="collision"></param>
		/// <param name="tf"></param>
		/// <returns></returns>
		public static int GetSymbolIntV(GameObject user, GameObject other)
		{
			float offset = user.transform.position.y - other.transform.position.y;
			if (offset > 0)
			{
				return -1;
			}
			return 1;
		}

		/// <summary>
		/// ����ÿ�е��Ӷ�������
		/// </summary>
		/// <param name="gridLayout"></param>
		/// <returns></returns>
		public static int CalculateGridItemsPerRow(GridLayoutGroup gridLayout)
		{
			RectTransform rectTransform = gridLayout.GetComponent<RectTransform>();

			float gridWidth = rectTransform.rect.width;
			float spacing = gridLayout.spacing.x;
			float itemWidth = gridLayout.cellSize.x + spacing;

			float availableWidth = gridWidth - gridLayout.padding.left - gridLayout.padding.right + spacing;
			int itemsPerRow = Mathf.FloorToInt(availableWidth / itemWidth);

			return itemsPerRow;
		}

		/// <summary>
		/// ����ÿ�е��Ӷ�������
		/// </summary>
		/// <param name="gridLayout"></param>
		/// <returns></returns>
		public static int CalculateItemsPerColumn(GridLayoutGroup gridLayout, float gridHeight)
		{
			RectTransform rectTransform = gridLayout.GetComponent<RectTransform>();
			// ��ȡ���񲼾ֵĴ�С�����

			float spacing = gridLayout.spacing.y;
			float itemHeight = gridLayout.cellSize.y + spacing;

			float availableWidth = gridHeight - gridLayout.padding.top - gridLayout.padding.bottom + spacing;
			int itemsPerColumn = Mathf.FloorToInt(availableWidth / itemHeight);

			return itemsPerColumn;
		}

		public static void SetScrollVerticalProgress(ScrollRect scrollRect, float verticalProgress)
		{
			// ���ƻ���������0��1֮��
			verticalProgress = 1 - Mathf.Clamp01(verticalProgress);

			// ����ScrollRect��vertical�����normalizedPosition����
			scrollRect.normalizedPosition = new Vector2(scrollRect.normalizedPosition.x, verticalProgress);
		}

		public static void SetScrollHorizontalProgress(ScrollRect scrollRect, float horizontalProgress)
		{
			// ���ƻ���������0��1֮��
			horizontalProgress = Mathf.Clamp01(horizontalProgress);

			// ����ScrollRect��vertical�����normalizedPosition����
			scrollRect.normalizedPosition = new Vector2(horizontalProgress, scrollRect.normalizedPosition.y);
		}
	}
}
